package com.aplink.generic.handler;

import java.util.ArrayList;

import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;

import com.aplink.generic.GenericApplication;
import com.aplink.generic.GenericFragment;
import com.aplink.generic.constant.type.ActionType;
import com.aplink.generic.constant.type.DialogStatus;
import com.aplink.generic.constant.type.ListViewSelection;
import com.aplink.generic.database.SqlMethods;
import com.aplink.generic.pojo.ContentData;
import com.aplink.generic.pojo.GenericObject;
import com.aplink.generic.pojo.ObjPropInfo;
import com.aplink.generic.sharepreference.GenericSharePreference;
import com.aplink.generic.util.Language;
import com.aplink.generic.webservice.DataResult;
import com.aplink.generic.widgets.ApLinkGallery;
import com.aplink.generic.widgets.ApLinkListView;

public class DataHandler extends Handler {
	private boolean isCloseDialog = true;
	private final GenericFragment mGenericFragment;
	private final ResponseHandler mGenericHandler;

	private final WebserviceHandler mWebserviceHandler;

	public DataHandler(final GenericFragment genericFragment) {
		this.mGenericFragment = genericFragment;
		this.mWebserviceHandler = genericFragment.getWebserviceHandler();
		this.mGenericHandler = genericFragment.getResponseHandler();
	}

	@SuppressWarnings("unchecked")
	@Override
	public void handleMessage(final Message msg) {
		final ContentData contentData = this.mGenericFragment.getContentData();
		ActionType actionType = ActionType.get(msg.what);
		final GenericObject genericObject = this.mGenericFragment
		        .getSelectedObject();
		DialogStatus alertDialogStatusType = null;
		if (actionType.equals(ActionType.LOGIN)) {
			alertDialogStatusType = login(msg, contentData,
			        alertDialogStatusType);
		} else if (actionType.equals(ActionType.INIT_DATA)) {
			final ArrayList<DataResult> dataResults = (ArrayList<DataResult>) msg.obj;
			this.mGenericFragment.getDatabaseInsert().initTables(dataResults);
			isCloseDialog = true;
			Language.getInstance().initDictionary();
			this.mGenericHandler.sendAction(ActionType.NEXT_PAGE);
		} else if (actionType.equals(ActionType.LOGIN_OFFLINE)) {
			final SqlMethods sqlMethods = this.mGenericFragment.getSqlMethods(
			        this.mGenericFragment.getMappingObject(),
			        this.mGenericFragment.getFormDesign().getSelectWhere());
			if (this.mGenericFragment.getDatabaseGet().isExists(contentData,
			        sqlMethods.toString())) {
				alertDialogStatusType = DialogStatus.SUCCESSFUL;
				this.mGenericHandler.sendAction(ActionType.NEXT_PAGE);
			} else {
				alertDialogStatusType = DialogStatus.FAILD;
			}
		} else if (actionType.equals(ActionType.DOWNLOAD)) {
			final ArrayList<DataResult> dataResults = (ArrayList<DataResult>) msg.obj;
			if (!dataResults.isEmpty()) {
				this.mGenericFragment.getDatabaseInsert().insertDownloadedList(
				        dataResults);
				alertDialogStatusType = DialogStatus.SUCCESSFUL;
				this.mGenericFragment.getResponseHandler().sendAction(
				        ActionType.REFRESH_PAGE);
			}
		} else if (actionType.equals(ActionType.DOWNLOAD_ALL)) {
			final ArrayList<DataResult> dataResults = (ArrayList<DataResult>) msg.obj;
			if (!dataResults.isEmpty()) {
				final ArrayList<String> ids = this.mGenericFragment
				        .getDatabaseInsert().insertDownloadedList(dataResults);
				if (ids.isEmpty()) {
					alertDialogStatusType = DialogStatus.FAILD;
				} else {
					alertDialogStatusType = DialogStatus.SUCCESSFUL;
				}
			}
		} else if (actionType.equals(ActionType.UPLOAD)) {
			final ArrayList<DataResult> dataResults = (ArrayList<DataResult>) msg.obj;
			if (this.mGenericFragment.getDatabaseUpdate().clearSyncStatus(
			        dataResults)) {
				alertDialogStatusType = DialogStatus.SUCCESSFUL;
			} else {
				alertDialogStatusType = DialogStatus.FAILD;
			}
		} else if (actionType.equals(ActionType.INSERT)) {
			alertDialogStatusType = insert(contentData, genericObject);
		} else if (actionType.equals(ActionType.UPDATE)) {
			alertDialogStatusType = update(contentData, genericObject);
		} else if (actionType.equals(ActionType.DELETE)) {
			if (this.mGenericFragment.getDatabaseDelete().delete(genericObject,
			        contentData) == null) {
				alertDialogStatusType = DialogStatus.FAILD;
			} else {
				alertDialogStatusType = DialogStatus.SUCCESSFUL;
				this.mGenericFragment.getResponseHandler().sendAction(
				        ActionType.REFRESH_PAGE);
			}
		} else if (actionType.equals(ActionType.SAVE)) {
			alertDialogStatusType = save(contentData, genericObject);
		} else if (actionType.equals(ActionType.FORGOT_PASSWORD)) {
			alertDialogStatusType = DialogStatus.SUCCESSFUL;
			this.mGenericFragment.getResponseHandler().sendAction(
			        ActionType.REFRESH_PAGE);
		}
		if (isCloseDialog) {
			if (this.mGenericFragment.getApLinkProgressDialog() != null) {
				this.mGenericFragment.getApLinkProgressDialog().dismiss();
			}
		}
		if (actionType.equals(ActionType.LOGIN_OFFLINE)) {
			actionType = ActionType.LOGIN;
		}
		this.mGenericFragment.getAlertDialog().show(actionType,
		        alertDialogStatusType);
	}

	private DialogStatus insert(final ContentData contentData,
	        final GenericObject genericObject) {
		DialogStatus alertDialogStatusType;
		String id = null;
		ApLinkGallery gallery = null;
		ApLinkListView listView = null;
		if (this.mGenericFragment.getFormDesign().isHasGallery()) {
			gallery = (ApLinkGallery) this.mGenericFragment
			        .getAPLinkViewByID(this.mGenericFragment.getFormDesign()
			                .getGalleryID());
			id = this.mGenericFragment.getDatabaseInsert().insert(
			        genericObject, this.mGenericFragment.getContentData(),
			        gallery.getInsertObjects(), gallery.getContentData());
		} else if (this.mGenericFragment.getFormDesign().isHasListView()) {
			listView = (ApLinkListView) this.mGenericFragment
			        .getAPLinkViewByID(this.mGenericFragment.getFormDesign()
			                .getListViewID());
			if (GenericSharePreference.getInstance().isOfflineMode()) {
				listView.getInsertList();
				listView.getDeleteList();
			}
			if (listView.getListViewSelection().equals(
			        ListViewSelection.MULTIPLE_SELECTION)) {
				final ArrayList<String> ids = this.mGenericFragment
				        .getDatabaseInsert().insert(listView.getArrInserts(),
				                contentData);
				if (ids.isEmpty()) {
					id = null;
				} else {
					id = ids.get(0);
				}
			} else if (listView.getListViewSelection().equals(
			        ListViewSelection.SINGLE_SELECTION)) {
				id = this.mGenericFragment.getDatabaseInsert().insert(
				        listView.getArrInserts().get(0), contentData);
			}
		} else {
			id = this.mGenericFragment.getDatabaseInsert().insert(
			        genericObject, contentData);
		}
		if (id == null) {
			alertDialogStatusType = DialogStatus.FAILD;
		} else {
			if (gallery != null) {
				gallery.clear();
			}
			alertDialogStatusType = DialogStatus.SUCCESSFUL;
			this.mGenericFragment.getResponseHandler().sendAction(
			        ActionType.REFRESH_PAGE);
		}
		return alertDialogStatusType;
	}

	private DialogStatus login(final Message msg,
	        final ContentData contentData, DialogStatus alertDialogStatusType) {
		if (msg.obj != null) {
			final DataResult dataResult = (DataResult) msg.obj;
			final ArrayList<GenericObject> objects = dataResult.getData();
			final GenericObject object = objects.get(0);
			String username = null;
			String token = null;
			for (int i = 0; i < dataResult.getContentData().size(); i++) {
				final ObjPropInfo propInfo = dataResult.getContentData()
				        .valueAt(i);
				if (propInfo.isUsername()) {
					username = object.getValue(propInfo).toString();
				}
				if (propInfo.isToken()) {
					token = object.getValue(propInfo).toString();
				}
			}
			if (this.mGenericFragment.getDatabaseInsert().insert(object,
			        contentData) != null) {
				alertDialogStatusType = DialogStatus.SUCCESSFUL;
				GenericApplication.getInstance().createLoginSession(username,
				        token);
				if (!GenericSharePreference.getInstance().isInvalidToken()) {
					if (mGenericFragment
					        .hasRegisterProgressDialog(ActionType.INIT_DATA)) {
						isCloseDialog = false;
						mGenericFragment
						        .getProgressDialog(ActionType.INIT_DATA).show();
					}
					this.mWebserviceHandler.sendAction(ActionType.INIT_DATA);
				}
				GenericSharePreference.getInstance().setInvalidToken(false);
			}
		} else {
			alertDialogStatusType = DialogStatus.FAILD;
		}
		return alertDialogStatusType;
	}

	private DialogStatus save(final ContentData contentData,
	        final GenericObject genericObject) {
		DialogStatus alertDialogStatusType;
		final String table = contentData.getMainTable();
		final ObjPropInfo primaryKey = contentData.getPrimaryKey(table);
		boolean isExists = false;
		if (TextUtils.isEmpty(genericObject.getValue(primaryKey
		        .getFullColumnName()))) {
			isExists = false;
		} else {
			isExists = this.mGenericFragment.getDatabaseGet().isExists(
			        genericObject, contentData);
		}
		String id = null;
		ApLinkGallery gallery = null;
		ApLinkListView listView = null;
		if (this.mGenericFragment.getFormDesign().isHasGallery()) {
			gallery = (ApLinkGallery) this.mGenericFragment
			        .getAPLinkViewByID(this.mGenericFragment.getFormDesign()
			                .getGalleryID());
			if (isExists) {
				id = this.mGenericFragment.getDatabaseUpdate().update(
				        genericObject, this.mGenericFragment.getContentData(),
				        gallery.getDeleteObjects(), gallery.getInsertObjects(),
				        gallery.getContentData());
			} else {
				id = this.mGenericFragment.getDatabaseInsert().insert(
				        genericObject, this.mGenericFragment.getContentData(),
				        gallery.getInsertObjects(), gallery.getContentData());
			}
		} else if (this.mGenericFragment.getFormDesign().isHasListView()) {
			listView = (ApLinkListView) this.mGenericFragment
			        .getAPLinkViewByID(this.mGenericFragment.getFormDesign()
			                .getListViewID());
			if (GenericSharePreference.getInstance().isOfflineMode()) {
				listView.getInsertList();
				listView.getDeleteList();
			}
			if (listView.getListViewSelection().equals(
			        ListViewSelection.MULTIPLE_SELECTION)) {
				if (isExists) {
					ArrayList<String> ids = null;
					if (!listView.getArrDeletes().isEmpty()) {
						ids = this.mGenericFragment.getDatabaseDelete().delete(
						        contentData, listView.getArrDeletes());
					}
					if (!listView.getArrInserts().isEmpty()) {
						ids = this.mGenericFragment.getDatabaseInsert().insert(
						        listView.getArrInserts(), contentData);
					}
					if (ids.isEmpty()) {
						id = null;
					} else {
						id = ids.get(0);
					}
				} else {
					final ArrayList<String> ids = this.mGenericFragment
					        .getDatabaseInsert().insert(
					                listView.getArrInserts(), contentData);
					if (ids.isEmpty()) {
						id = null;
					} else {
						id = ids.get(0);
					}
				}
			} else if (listView.getListViewSelection().equals(
			        ListViewSelection.SINGLE_SELECTION)) {
				if (isExists) {
					id = this.mGenericFragment.getDatabaseUpdate().update(
					        listView.getArrInserts().get(0), contentData);
				} else {
					id = this.mGenericFragment.getDatabaseInsert().insert(
					        listView.getArrInserts().get(0), contentData);
				}
			}

		} else {
			if (isExists) {
				id = this.mGenericFragment.getDatabaseUpdate().update(
				        genericObject, contentData);
			} else {
				id = this.mGenericFragment.getDatabaseInsert().insert(
				        genericObject, contentData);
			}
		}
		if (id == null) {
			alertDialogStatusType = DialogStatus.FAILD;
		} else {
			if (gallery != null) {
				gallery.clear();
			}
			alertDialogStatusType = DialogStatus.SUCCESSFUL;
			this.mGenericFragment.getResponseHandler().sendAction(
			        ActionType.REFRESH_PAGE);
		}
		return alertDialogStatusType;
	}

	public void sendAction(final ActionType actionType) {
		sendEmptyMessage(actionType.getCode());
	}

	public void sendMessage(final ActionType actionType, final Object object) {
		final Message message = Message.obtain(this, actionType.getCode(),
		        object);
		message.sendToTarget();
	}

	private DialogStatus update(final ContentData contentData,
	        final GenericObject genericObject) {
		DialogStatus alertDialogStatusType;
		final String table = contentData.getMainTable();
		final ObjPropInfo primaryKey = contentData.getPrimaryKey(table);
		boolean isExists = false;
		if (TextUtils.isEmpty(genericObject.getValue(primaryKey
		        .getFullColumnName()))) {
			isExists = false;
		} else {
			isExists = this.mGenericFragment.getDatabaseGet().isExists(
			        genericObject, contentData);
		}
		String id = null;
		ApLinkGallery gallery = null;
		ApLinkListView listView = null;
		if (this.mGenericFragment.getFormDesign().isHasGallery()) {
			gallery = (ApLinkGallery) this.mGenericFragment
			        .getAPLinkViewByID(this.mGenericFragment.getFormDesign()
			                .getGalleryID());
			if (isExists) {
				id = this.mGenericFragment.getDatabaseUpdate().update(
				        genericObject, this.mGenericFragment.getContentData(),
				        gallery.getDeleteObjects(), gallery.getInsertObjects(),
				        gallery.getContentData());
			}
		} else if (this.mGenericFragment.getFormDesign().isHasListView()) {
			listView = (ApLinkListView) this.mGenericFragment
			        .getAPLinkViewByID(this.mGenericFragment.getFormDesign()
			                .getListViewID());
			if (GenericSharePreference.getInstance().isOfflineMode()) {
				listView.getInsertList();
				listView.getDeleteList();
			}
			if (listView.getListViewSelection().equals(
			        ListViewSelection.MULTIPLE_SELECTION)) {
				if (isExists) {
					ArrayList<String> ids = null;
					if (!listView.getArrDeletes().isEmpty()) {
						ids = this.mGenericFragment.getDatabaseDelete().delete(
						        contentData, listView.getArrDeletes());
					}
					if (!listView.getArrInserts().isEmpty()) {
						ids = this.mGenericFragment.getDatabaseInsert().insert(
						        listView.getArrInserts(), contentData);
					}
					if (ids.isEmpty()) {
						id = null;
					} else {
						id = ids.get(0);
					}
				}
			} else if (listView.getListViewSelection().equals(
			        ListViewSelection.SINGLE_SELECTION)) {
				if (isExists) {
					id = this.mGenericFragment.getDatabaseUpdate().update(
					        listView.getArrInserts().get(0), contentData);
				}
			}

		} else {
			if (isExists) {
				id = this.mGenericFragment.getDatabaseUpdate().update(
				        genericObject, contentData);
			}
		}
		if (id == null) {
			alertDialogStatusType = DialogStatus.FAILD;
		} else {
			if (gallery != null) {
				gallery.clear();
			}
			alertDialogStatusType = DialogStatus.SUCCESSFUL;
			this.mGenericFragment.getResponseHandler().sendAction(
			        ActionType.REFRESH_PAGE);
		}
		return alertDialogStatusType;
	}
}
